<?php

//
// Edit History:
//
//  Last $Author: munroe $
//  Last Modified: $Date: 2006/09/26 14:39:46 $
//
//  Dick Munroe (munroe@csworks.com) 28-Feb-2006
//      Initial version created
//
//	Dick Munroe (munroe@csworks.com) 25-Sep-2006
//		1.0.1
//			Changes for PHP 5.0 compatibility.
//
//

/**
 * @author Dick Munroe <munroe@csworks.com>
 * @copyright copyright @ 2006 by Dick Munroe, Cottage Software Works, Inc.
 * @license http://www.csworks.com/publications/ModifiedNetBSD.html
 * @version 1.0.1
 * @package dm.paypal
 * @example ./example.php
 *
 * This is derived from a paypal IPN class written originally by Herve Foucher
 * <Herve.Foucher@helio.org> and published through phpclasses.org under the GPL.
 * Herve appears to no longer support this package so I'm updating the support
 * to 2005 and redesigning a bunch of the internal structure to allow a substantially
 * more object oriented approach to the whole problem.
 *
 * There should be data which can appear in more than one place in the IPN specifications
 * or is necessary to get the class itself working in the base class.  Naming conventions
 * that guarantee no collisions with the Paypal variables in the IPN post are chosen.
 */

class paypalIPNDataBase
{
    /*
     * These should be common to ALL IPN interactions.
     */

    var $test_ipn ;
    var $notify_version ;

    /*
     * This isn't documented anywhere, but from the Paypal website...
     */

    var $receipt_id ; 					// You get a receipt id when a buyer makes a payment
							// without having a paypal account. That is the buyer's
							// receipt id, not ours. We get an authnumber through
							// the IPN this is what you store in your database.
							// You have to grab the authnumber returned by the IPN.
    var $charset ;					// Apparently this defines the character set encoding
							// used by the notification.  This is not used at this time
							// by these classes.
    /*
     * The following are common to some (not all) IPN interactions.
     */

    var $tax ;
    var $txn_type ;
    var $txn_id ;

    /**
     * @var boolean true if this object contains data, false otherwise.
     * @access public
     */

    var $m_dirty ;

    /**
     * @var array contains patterns of the form:
     *
     *	/^aRegularExpression$/
     *
     * Which will be used to probe the source for items which should go into the
     * object (and it's derived objects).  Due to the necessity of dealing with
     * retrospection all data actually winds up stored in the most derived object.
     * New patterns are added by either $this->m_IPNVariableNamePatterns[] or by
     * and array_merge.
     * @access protected
     */

    var $m_IPNVariableNamePatterns ;

    var $m_dynamicVariables ;

    /**
     * @var string Encrypted string used to validate the authenticity of the
     * 		   transaction.
     * @access public
     */

    var $verify_sign ;

    /**
     * Constructor.
     *
     * Pull the arguments passed in the source array into the
     * IPN data object.
     *
     * @param	array	$theSource [by reference] The source array containing the variables to
     * 			be pulled into the IPN data object.
     * @param	array	$theIPNVariableNamePatterns [by value] The contains patterns for dynamicall
     * 					named variables.  Used only by Basic and Mass Payment currently.
     * @return  void
     * @access  public
     */

    function paypalIPNDataBase (&$theSource, $theIPNVariableNamePatterns = NULL)
    {
		$this->m_dynamicVariables = array() ;
		$this->m_IPNVariableNamePatterns = $theIPNVariableNamePatterns;

		/*
		 * This all works because the variables defined at the class level
         * are the set of variables (except for shopping cart variables) that
         * are to be pulled from the $_POST array.  The variable names are
         * taken from the IPN documentation available from Paypal.
		 */

		$vars = get_object_vars ($this) ;

		$this->m_dirty = FALSE ;

		foreach ($theSource as $theVariableName => $theValue)
		{
		    if (array_key_exists($theVariableName, $vars))
		    {
				$this->$theVariableName =& $theSource[$theVariableName] ;

				$this->m_dirty = TRUE ;
				unset($theSource[$theVariableName]) ;
			}
		}

		/*
		 * A second pass needs to be made if there were any variable name
		 * patterns defined by derived classes.
		 */

		if (!is_null($this->m_IPNVariableNamePatterns) && $this->processVariableNamePatterns())
		{
			foreach ($theSource as $theVariableName => $theValue)
			{
				foreach ($this->m_IPNVariableNamePatterns as $theCartVariablePattern)
				{
					if (preg_match($theCartVariablePattern, $theVariableName, $theMatch) != 0)
					{
						/*
						 * Note that all the data matched by these patterns is stored in the most
						 * derived class due to limitations on addressing specific classes within
						 * the derivation tree.
						 */

						$this->m_dynamicVariables[$theMatch[0]] =& $theSource[$theVariableName] ;

						$this->m_dirty = TRUE ;

						unset($theSource[$theMatch[0]]) ;
					}
				}
			}
		}
	}

    /**
     * @desc predicate for checking whether or not to process variable names via preg_match.
     * @return boolean true if variable name patterns are to be processed.
     * @access protected
     */

    function processVariableNamePatterns()
    {
	return TRUE ;
    }
}

?>
